﻿#include "myqsqlfactory.h"
/******************************************************************************
  @Project Name  : 04TestConnectMysql
  @File Name     : myqsqlfactory.cpp
  @Version       : 1.0
  @Function      : to be determined
  @Author        : unishuai
  @Date          : 2024-05-22
******************************************************************************/
#ifndef MY_DEBUG_INFO
#define MY_DEBUG_INFO true
#endif



MyQSqlFactory& MyQSqlFactory::Instance()
{
    static MyQSqlFactory instance(nullptr);
    if(instance.m_IsInit == false)
        instance.Init();
    return instance;
}

bool MyQSqlFactory::Init()
{
    if(m_IsInit == true)
        return true;

    /**=================by unishuai====================
    *我感觉这个内容还是写到Factory里面比较合适
    *===================2024-05-22 ====================*/

    m_IsInit = true;
    return m_IsInit;
}

MyQSqlFactory::MyQSqlFactory(QObject *parent) : QObject(parent),m_IsInit(false)
{
    //初始化连接
    initialSqlCon();
}

QSqlQuery MyQSqlFactory::getQuery() const
{
    return query;
}

void MyQSqlFactory::setQuery(const QSqlQuery &value)
{
    query = value;
}

QSqlDatabase MyQSqlFactory::getDb() const
{
    return m_db;
}

void MyQSqlFactory::setDb(const QSqlDatabase &db)
{
    m_db = db;
}

QString MyQSqlFactory::getTableName() const
{
    return tableName;
}

void MyQSqlFactory::setTableName(const QString &value)
{
    tableName = value;
}


void MyQSqlFactory::initialSqlCon()
{
    QSettings settingsDB("./configFile/configDB.ini",QSettings::IniFormat);
    // 数据库的那个小的一节
    settingsDB.beginGroup("database");
    QString dbtype=settingsDB.value("dbtype").toString();
    QString hostname=settingsDB.value("hostname").toString();
    QString dbname=settingsDB.value("dbname").toString();
    QString username=settingsDB.value("username").toString();
    QString password=settingsDB.value("password").toString();
    settingsDB.endGroup();


    // 打开数据库
    // 使用 QMYSQL 数据库驱动
    //    qDebug()<<"dbtype:"<<dbtype;
    //    qDebug()<<"hostname:"<<hostname;
    //    qDebug()<<"dbname:"<<dbname;
    //    qDebug()<<"username:"<<username;
    //    qDebug()<<"password:"<<password;

    m_db = QSqlDatabase::addDatabase(dbtype);
    // 设置数据库名称
    // 数据库名为
    m_db.setDatabaseName(dbname);

    // 设置数据库用户名和密码
    // 用户名为 root，密码为
    m_db.setUserName(username);
    m_db.setPassword(password);

    // 设置数据库服务器地址
    // 服务器地址为 localhost
    m_db.setHostName(hostname);

    //连接数据库
    if (!m_db.open()) {
        qDebug() << "Database connection failed:" << m_db.lastError().text();
        return;
    }

    //初始化查询
    query=QSqlQuery(m_db);


    //    // 打开数据库
    //    // 使用 QMYSQL 数据库驱动
    //    QSqlDatabase m_db = QSqlDatabase::addDatabase("QMYSQL");
    //    // 设置数据库名称
    //    // 数据库名为
    //    m_db.setDatabaseName("demo");

    //    // 设置数据库用户名和密码
    //    // 用户名为 root，密码为
    //    m_db.setUserName("root");
    //    m_db.setPassword("123");

    //    // 设置数据库服务器地址
    //    // 服务器地址为 localhost
    //    m_db.setHostName("localhost");


    // 打开数据库
    // 并输出打开结果到调试信息
    //    qDebug() <<" 数据库连接："+ m_db.open();
    //    qDebug() <<QSqlDatabase::drivers();
}

void MyQSqlFactory::createTable()
{

    if(tableName.isEmpty()){
        //简单来说，就是第一次开始运行的时候创建一个表格
        qint64 timeStamp = QDateTime::currentMSecsSinceEpoch();
        tableName="sysinfo"+QDateTime::currentDateTime().toString("_yyyyMMdd_")+ QString::number(timeStamp);
    }

    //    执行创建表格的语句
    QString createTableSql = QString(
                "CREATE TABLE IF NOT EXISTS `%1` ("
                "`id` INT(12) NOT NULL AUTO_INCREMENT, "
                "`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
                "`slider01` DOUBLE NOT NULL COMMENT '滑块1滑动的距离', "
                "`slider02` DOUBLE NOT NULL COMMENT '滑块2滑动的距离', "
                "`slider03` DOUBLE NOT NULL COMMENT '滑块3滑动的距离', "
                "`slider04` DOUBLE NOT NULL COMMENT '滑块4滑动的距离', "
                "`slider05` DOUBLE NOT NULL COMMENT '滑块5滑动的距离', "
                "`slider06` DOUBLE NOT NULL COMMENT '滑块6滑动的距离', "
                "`attack_ag` DOUBLE NOT NULL COMMENT '控制飞机的俯仰(滚转机构滚转角)', "
                "`roll_ag` DOUBLE NOT NULL COMMENT '控制导弹的旋转(攻角机构角度)', "
                "`dual_axis_ag01` DOUBLE COMMENT '双转轴转角1', "
                "`dual_axis_ag02` DOUBLE COMMENT '双转轴转角2', "
                "`mp_x` DOUBLE COMMENT '动平台机构(六爪)的X坐标', "
                "`mp_y` DOUBLE COMMENT '动平台机构(六爪)的Y坐标', "
                "`mp_z` DOUBLE COMMENT '动平台机构(六爪)的Z坐标', "
                "`mp_rx` DOUBLE COMMENT '动平台机构(六爪)的绕X轴旋转', "
                "`mp_ry` DOUBLE COMMENT '动平台机构(六爪)的绕Y轴旋转', "
                "`mp_rz` DOUBLE COMMENT '动平台机构(六爪)的绕Z轴旋转', "
                "PRIMARY KEY (`id`))"
                ).arg(tableName);



    if(!query.exec(createTableSql)){
        qDebug() << "Failed to create table:" << query.lastError().text();
    }else{
        if(MY_DEBUG_INFO){
            qDebug() <<"table("<<tableName<< ") created successfully";
        }
    }


}

void MyQSqlFactory::insertSimDataTest()
{
    //这里做一个测试
    //SimSystemInfo sysInfo(959.099,1064.990,901.115,602.824,738.283,638.543,0.0,0.0);
    //    insertSimDataWithNoMotionInfo(sysInfo);

    SimSystemInfo sysInfo(959.099,1064.990,901.115,602.824,738.283,638.543,0.0,0.0,1600,-70,248,0,0,0);
    insertSimData(sysInfo);







}

void MyQSqlFactory::insertSimDataWithNoMotionInfo(SimSystemInfo sysInfo)
{
    if(tableName.isEmpty()){
        qDebug()<<"tableName is not exits or not select(dazhi yisi ,buhui yingyu)";
        return;
    }
    QString insertSql=QString("INSERT INTO `%1` ("
                              "slider01, slider02, slider03, slider04, slider05, slider06, "
                              "attack_ag, roll_ag) "
                              "VALUES (:slider01, :slider02, :slider03, :slider04, :slider05, :slider06, "
                              ":attack_ag, :roll_ag)").arg(tableName);
    query.prepare(insertSql);
    // 绑定从SimSystemInfo实例传来的值
    query.bindValue(":slider01", sysInfo.getSlider01());
    query.bindValue(":slider02", sysInfo.getSlider02());
    query.bindValue(":slider03", sysInfo.getSlider03());
    query.bindValue(":slider04", sysInfo.getSlider04());
    query.bindValue(":slider05", sysInfo.getSlider05());
    query.bindValue(":slider06", sysInfo.getSlider06());
    query.bindValue(":attack_ag", sysInfo.getAttack_ag());
    query.bindValue(":roll_ag", sysInfo.getRoll_ag());

    if (!query.exec()) {
        qDebug() << "Insert into" << tableName << "failed:" << query.lastError();
    } else {
        if(MY_DEBUG_INFO){
            qDebug() << "Data inserted into" << tableName << "successfully!";
        }

    }

}

void MyQSqlFactory::insertSimData(SimSystemInfo sysInfo)
{
    QSqlQuery query;
    if(tableName.isEmpty()){
        qDebug()<<"tableName is not exits or not select(dazhi yisi ,buhui yingyu)";
        return ;
    }

    // 准备插入语句
    QString sql = QString("INSERT INTO `%1` (slider01, slider02, slider03, slider04, slider05, slider06, "
                          "attack_ag, roll_ag, mp_x, mp_y, mp_z, mp_rx, mp_ry, mp_rz) "
                          "VALUES (:slider01, :slider02, :slider03, :slider04, :slider05, :slider06, "
                          ":attack_ag, :roll_ag, :mp_x, :mp_y, :mp_z, :mp_rx, :mp_ry, :mp_rz)").arg(tableName);

    // 准备查询
    if (!query.prepare(sql)) {
        qDebug() << "insertSimData(SimSystemInfo sysInfo) Prepare failed:" << query.lastError().text();
        return ;
    }

    // 绑定参数
    query.bindValue(":slider01", sysInfo.getSlider01());
    query.bindValue(":slider02", sysInfo.getSlider02());
    query.bindValue(":slider03", sysInfo.getSlider03());
    query.bindValue(":slider04", sysInfo.getSlider04());
    query.bindValue(":slider05", sysInfo.getSlider05());
    query.bindValue(":slider06", sysInfo.getSlider06());
    query.bindValue(":attack_ag", sysInfo.getAttack_ag());
    query.bindValue(":roll_ag", sysInfo.getRoll_ag());
    query.bindValue(":mp_x", sysInfo.getMp_x());
    query.bindValue(":mp_y", sysInfo.getMp_y());
    query.bindValue(":mp_z", sysInfo.getMp_z());
    query.bindValue(":mp_rx", sysInfo.getMp_rx());
    query.bindValue(":mp_ry", sysInfo.getMp_ry());
    query.bindValue(":mp_rz", sysInfo.getMp_rz());

    // 执行查询
    if (!query.exec()) {
        qDebug() << "insertSimData(SimSystemInfo sysInfo) Insert failed:" << query.lastError().text();
        return ;
    }else {
        if(MY_DEBUG_INFO){
            qDebug() << "Data inserted into" << tableName << "successfully!";
        }

    }



}

bool MyQSqlFactory::readSimData(QString historyTableName)
{
    if(historyTableName.isEmpty()||historyTableName.size()<1){
        qDebug() << "readSimData(QString historyTableName) exec failed:" << query.lastError().text();
        return false;
    }

    QString sql = QString("SELECT "
                          "slider01, slider02, slider03, "
                          "slider04, slider05, slider06, "
                          "attack_ag,roll_ag "
                          "FROM %1 ORDER BY created_at ASC ").arg(tableName);
    if(!query.exec(sql)){
        qDebug() << "readSimData(QString historyTableName) exec failed:" << query.lastError().text();
        return false;
    }

    //    QVector<
    while (query.next()) {
        double slider01Tmp = query.value(0).toDouble();
        double slider02Tmp = query.value(1).toDouble();
        double slider03Tmp = query.value(2).toDouble();
        double slider04Tmp = query.value(3).toDouble();
        double slider05Tmp = query.value(4).toDouble();
        double slider06Tmp = query.value(5).toDouble();
        double attack_agTmp=query.value(6).toDouble();
        double roll_agTmp=query.value(7).toDouble();

        SimSystemInfo data(slider01Tmp,slider02Tmp,slider03Tmp,
                           slider04Tmp,slider05Tmp,slider06Tmp,
                           attack_agTmp,roll_agTmp
                           );
        //if(MY_DEBUG_INFO){
        //  qDebug() <<
        //}
        std::cout<<data<<std::endl;
    }



}


bool MyQSqlFactory::checkIfTableExists(const QString& tmptableName) {
    query.prepare("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = :dbname AND table_name = :tablename)");
    query.bindValue(":dbname", this->m_db.databaseName());
    query.bindValue(":tablename", tmptableName);

    if (!query.exec()) {
        qDebug() << "no such table" << query.lastError().text();
        return false;
    }

    if (query.next()) {
        //这里讲查询的结果进行转换，查到了就是1，没有查到就是0
        return query.value(0).toBool();
    }
    return false;
}


bool MyQSqlFactory::isTableEmpty(const QString& tableName) {
    QSqlQuery query;
    query.prepare("SELECT 1 FROM " + tableName + " LIMIT 1");

    if (!query.exec()) {
        qDebug() << "查询失败：" << query.lastError().text();
        return true; // 如果查询失败，假定表为空或存在问题
    }

    return !query.next(); // 如果能够读取到数据，query.next() 为 true，表不为空
}

bool MyQSqlFactory::dropTable( const QString& tmptableName) {
    if (!this->m_db.isOpen()) {
        qDebug() << "Database is not open!";
        return false;
    }

    QSqlQuery query(this->m_db);
    QString sql = QString("DROP TABLE IF EXISTS %1").arg(tmptableName);

    if (query.exec(sql)) {
        qDebug() << "Table" << tmptableName << "has been dropped successfully.";
        return true;
    } else {
        qDebug() << "Failed to drop table" << tmptableName << ":" << query.lastError().text();
        return false;
    }
}


